#ifndef __IQMATH_H__
#define __IQMATH_H__

#ifdef __cplusplus
extern "C"
{
#endif

	typedef signed long int _qi_, iqq;
	typedef unsigned long int _qu_, uqq;
	typedef signed long long int _dqi_;
	typedef unsigned long long int _dqu_;
	typedef signed short int _sqi_;
	typedef unsigned short int _squ_;

#define QI(x) ((_qi_)(x))
#define QU(x) ((_qu_)(x))
#define QDI(x) ((_dqi_)(x))
#define QDU(x) ((_dqu_)(x))
#define QSI(x) ((_sqi_)(x))
#define QSU(x) ((_squ_)(x))

#define QI_TO_Q(QN, x) ((_qi_)((_qi_)(x)) * (_qi_)(1 << QN))
#define QU_TO_Q(QN, x) ((_qu_)((_qu_)(x)) * (_qu_)(1 << QN))

#define QU_TO_INT(QN, x) ((x)&0x80000000) ? (((x) >> QN) | (UINT32_MAX << (32 - QN))) : ((x) >> QN)
#define QU_TO_FLT(QN, x) ((float)(x) / (1 << QN))

#define Q_ADD(X1, X2) ((X1) + (X2))
#define Q_SUB(X1, X2) ((X1) - (X2))

#define QI_MUL(QN, X1, X2) QDI(QDI((QI(X1) * QI(X2))) >> (QN))
#define QU_MUL(QN, X1, X2) QDI(QDU((QU(X1) * QU(X2))) >> (QN))

#define QIS_MUL(QN, X1, X2) QI(QI((QI(X1) * QI(X2))) / QI_TO_Q(QN, 1))
#define QUS_MUL(QN, X1, X2) QU(QU((QU(X1) * QU(X2))) >> (QN))

#define QI_DIV(QN, Y, D) QI(QDI((QI(Y) * QI_TO_Q(QN, 1))) / QI(D))
#define QU_DIV(QN, Y, D) QU(QDU((QU(Y) * QU_TO_Q(QN, 1))) / QU(D))

#define QIS_DIV(QN, Y, D) QI(QI((QI(Y) * QI_TO_Q(QN, 1))) / QI(D))
#define QUS_DIV(QN, Y, D) QU(QU((QU(Y) * QU_TO_Q(QN, 1))) / QU(D))

#define QI_MUL_DIV(QN, X1, X2, D) QI(QDI((QI(X1) * QI(X2))) / QI(D))
#define QU_MUL_DIV(QN, X1, X2, D) QU(QDU((QU(X1) * QU(X2))) / QU(D))

#define QIS_MUL_DIV(QN, X1, X2, D) QI(QI((QI(X1) * QI(X2))) / QI(D))
#define QUS_MUL_DIV(QN, X1, X2, D) QU(QU((QU(X1) * QU(X2))) / QU(D))

#define DEC_PS0 1
#define DEC_PS1 10
#define DEC_PS2 100
#define DEC_PS3 1000
#define DEC_PS4 10000
#define DEC_PS5 100000
#define DEC_PS6 1000000
#define DEC_PS7 10000000

#define DEC_TO_P(N, x) (x * DEC_PS##N)
#define DEC_TO_INT(N, x) ((int)x / DEC_PS##N)
#define DEC_TO_FLOAT(N, x) ((float)x / DEC_PS##N)

#ifdef __cplusplus
}
#endif

#endif 
